home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / System / popup-menu-cdef ƒ / pup.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-04-15  |  6.2 KB  |  269 lines  |  [TEXT/KAHL]

  1. /*
  2.  * pup.c
  3.  *
  4.  * Copyright © 1990 Michael S. Engber. All rights reserved
  5.  */
  6.  
  7. #include "pup.h"
  8.  
  9. #define INDENT 5
  10. #define XTRA_INDENT 9
  11.  
  12.  
  13. static Rect PupMenuRect(ControlHandle theControl, Str255 curItem){
  14. /*
  15.  * Returns the pop-up box for curItem & trims curItem if needed.
  16.  */
  17.     MenuHandle    menuH    = (MenuHandle)(*theControl)->contrlData;
  18.     Rect        r        = (*theControl)->contrlRect;
  19.     Point        p        = *(Point*)(&(*theControl)->contrlRfCon);
  20.     int            maxWid;
  21.  
  22.     GetItem(menuH,(*theControl)->contrlValue,curItem);
  23.  
  24.     r.left    = p.h;
  25.     r.bottom = p.v;
  26.  
  27.     maxWid = r.right - r.left - 2*INDENT - XTRA_INDENT - 1;
  28.     
  29.     while(curItem[0]>1 && StringWidth(curItem)>maxWid){
  30.         --curItem[0];
  31.         curItem[curItem[0]] = '…';
  32.     }
  33.     
  34.     r.right    = r.left + StringWidth(curItem) + 2*INDENT + XTRA_INDENT;
  35.     
  36.     OffsetRect(&r,0,1);
  37.     return r;
  38. }
  39.  
  40.  
  41. static Rect PupTitleRect(ControlHandle theControl){
  42.     MenuHandle    menuH    = (MenuHandle)(*theControl)->contrlData;
  43.     Rect        r        = (*theControl)->contrlRect;
  44.     Point        p        = *(Point*)(&(*theControl)->contrlRfCon);
  45.  
  46.     r.right        = p.h;
  47.     r.bottom    = p.v;
  48.     r.left        = r.right - 2*INDENT - StringWidth((*menuH)->menuData);
  49.  
  50.     OffsetRect(&r,0,1);
  51.     return r;
  52. }
  53.  
  54. /*----------------------------------------------------------------------*/
  55.  
  56. static long DrawCntl(ControlHandle theControl, long param){
  57.     MenuHandle    menuH    = (MenuHandle)(*theControl)->contrlData;
  58.     Rect        menuRect;
  59.     Str255        curItem;
  60.     FontInfo    fInfo;
  61.  
  62.     if(!(*theControl)->contrlVis) return 0L;
  63.  
  64.     menuRect    = PupMenuRect(theControl,curItem);
  65.     GetFontInfo(&fInfo);
  66.  
  67.     EraseRect(&(*theControl)->contrlRect);
  68.     
  69.     MoveTo(menuRect.left - INDENT - StringWidth((*menuH)->menuData),
  70.             menuRect.top + fInfo.ascent);
  71.     DrawString((*menuH)->menuData);
  72.     
  73.     MoveTo(menuRect.left + INDENT + XTRA_INDENT,
  74.             menuRect.top + fInfo.ascent);
  75.  
  76.     DrawString(curItem);
  77.  
  78.     
  79.     InsetRect(&menuRect,-1,-1);
  80.     FrameRect(&menuRect);
  81.     MoveTo(menuRect.left + 2,menuRect.bottom);
  82.     LineTo(menuRect.right,menuRect.bottom);
  83.     LineTo(menuRect.right,menuRect.top + 2);
  84.  
  85.     return 0L;
  86. }
  87.  
  88. static long TestCntl(ControlHandle theControl, long param){
  89.     Rect    menuRect;
  90.     Str255    curItem;
  91.     
  92.     menuRect = PupMenuRect(theControl,curItem);
  93.     if ((*theControl)->contrlHilite!=255 && PtInRect(param,&menuRect))
  94.         return (long)inThumb;
  95.     else
  96.         return 0L;
  97. }
  98.  
  99. static long CalcCRgns(ControlHandle theControl, long param){
  100.     RectRgn((RgnHandle)param,&(*theControl)->contrlRect);
  101.     return 0L;
  102. }
  103.  
  104. static long InitCntl(ControlHandle theControl, long param){
  105.     FontInfo    fInfo;
  106.     Point        p;
  107.  
  108.     /* first try to use contrlMin as the rsrc id of a MENU */
  109.     if((*theControl)->contrlMin > 0)
  110.         (*theControl)->contrlData = (Handle)GetMenu((*theControl)->contrlMin);
  111.     else{
  112.         (*theControl)->contrlMin  = Unique1ID('MENU');
  113.         (*theControl)->contrlData = (Handle)0L;
  114.     }
  115.         
  116.     /* if above fails, create a menu with id = cntrlMin */
  117.     if(!(*theControl)->contrlData)
  118.         (*theControl)->contrlData = (Handle)NewMenu((*theControl)->contrlMin,
  119.                                                     (*theControl)->contrlTitle);
  120.  
  121.     /* bottom right point of pop-up title box */    
  122.     GetFontInfo(&fInfo);
  123.     p.h = (*theControl)->contrlRect.left + (*theControl)->contrlMax;
  124.     p.v = (*theControl)->contrlRect.top + fInfo.ascent + fInfo.descent + fInfo.leading;
  125.     
  126.     /* Set Min & Max - set Max really large in case items are added later */
  127.     (*theControl)->contrlMin = 1;
  128.     (*theControl)->contrlMax = 9999;
  129.  
  130.     /* contrlRfCon holds ResType the menu lists - 0 if none */
  131.     if((*theControl)->contrlRfCon)
  132.         AddResMenu((MenuHandle)(*theControl)->contrlData,
  133.             (ResType)(*theControl)->contrlRfCon);
  134.             
  135.     /* store bottom right point of pop-up title box in contrlRfCon */
  136.     *(Point*)(&(*theControl)->contrlRfCon) = p;
  137.  
  138.  
  139.     return 0L;
  140. }
  141.  
  142. static long DispCntl(ControlHandle theControl, long param){
  143.     MenuHandle    menuH    = (MenuHandle)(*theControl)->contrlData;
  144.     
  145.     if(HomeResFile(menuH) > 0){
  146.         ReleaseResource(menuH);
  147.     }else{
  148.         DisposeMenu(menuH);
  149.     }
  150.  
  151.     return 0L;
  152. }
  153.  
  154. static long PosCntl(ControlHandle theControl, long param){
  155.     return 0L;
  156. }
  157.  
  158. static long ThumbCntl(ControlHandle theControl, long param){
  159.     return 0L;
  160. }
  161.  
  162. static long DragCntl(ControlHandle theControl, long param){
  163.     MenuHandle    menuH        = (MenuHandle)(*theControl)->contrlData;
  164.     Rect        menuRect;
  165.     Rect        titleRect    = PupTitleRect(theControl);
  166.     Str255        curItem;
  167.     short        oldItem;
  168.     short        newItem;
  169.  
  170.     Point        popPt;
  171.     
  172.     if(param == 0L) return 0L;
  173.     
  174.     InvertRect(&titleRect);
  175.     
  176.     menuRect = PupMenuRect(theControl,curItem);
  177.     oldItem = (*theControl)->contrlValue;
  178.  
  179.     CheckItem(menuH,oldItem,(char)1);
  180.     
  181.     popPt.v = menuRect.top;
  182.     popPt.h = menuRect.left;
  183.     LocalToGlobal(&popPt);
  184.     
  185.     InsertMenu(menuH,-1);
  186.     newItem = LoWord(PopUpMenuSelect(menuH,popPt.v,popPt.h ,oldItem));
  187.     DeleteMenu((*menuH)->menuID);
  188.  
  189.     if(newItem > 0) (*theControl)->contrlValue = newItem;
  190.     
  191.     
  192.     CheckItem(menuH,oldItem,(char)0);
  193.  
  194.     DrawCntl(theControl,0L);    
  195.  
  196.     return 1L;
  197. }
  198.  
  199. static long AutoTrack(ControlHandle theControl, long param){
  200.     return 0L;
  201. }
  202.  
  203. /*----------------------------------------------------------------------*/
  204.  
  205. pascal long mainCDEF(int varCode, ControlHandle theControl, int message, long param){
  206.     long        result;
  207.     SignedByte    hState;
  208.     GrafPtr        gPort;
  209.     PenState    pState;
  210.     short        tSize;
  211.     short        tFont;
  212.     Style        tFace;
  213.     short        tMode;
  214.     RgnHandle    clipRgn;
  215.     RgnHandle    updateRgn;
  216.     
  217.     hState = HGetState(theControl);
  218.     HLock(theControl);
  219.  
  220.  
  221.     clipRgn = NewRgn();
  222.     GetClip(clipRgn);
  223.     GetPort(&gPort);
  224.     GetPenState(&pState);
  225.     tSize    = gPort->txSize;
  226.     tFont    = gPort->txFont;
  227.     tFace    = gPort->txFace;
  228.     tMode    = gPort->txMode;
  229.  
  230.  
  231.     updateRgn = NewRgn();
  232.     RectRgn(updateRgn,&(*theControl)->contrlRect);
  233.     SectRgn(updateRgn,clipRgn,updateRgn);
  234.     SetClip(updateRgn);
  235.     DisposeRgn(updateRgn);
  236.  
  237.     PenNormal();
  238.     TextSize(12);
  239.     TextFont(systemFont);
  240.     TextFace(0);
  241.     TextMode(srcCopy);
  242.  
  243.     
  244.     switch(message){
  245.         case drawCntl:    result = DrawCntl(theControl,param);    break;
  246.         case testCntl:    result = TestCntl(theControl,param);    break;
  247.         case calcCRgns: result = CalcCRgns(theControl,param);    break;
  248.         case initCntl:    result = InitCntl(theControl,param);    break;
  249.         case dispCntl:    result = DispCntl(theControl,param);    break;
  250.         case posCntl:    result = PosCntl(theControl,param);        break;
  251.         case thumbCntl:    result = ThumbCntl(theControl,param);    break;
  252.         case dragCntl:    result = DragCntl(theControl,param);    break;
  253.         case autoTrack:    result = AutoTrack(theControl,param);    break;
  254.     }
  255.  
  256.  
  257.     SetPenState(&pState);
  258.     TextSize(tSize);
  259.     TextFont(tFont);
  260.     TextFace(tFace);
  261.     TextMode(tMode);
  262.  
  263.     SetClip(clipRgn);
  264.     DisposeRgn(clipRgn);
  265.  
  266.  
  267.     HSetState(theControl,hState);
  268.     return result;
  269. }